package com.rjwh.dingdong.client.download;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.aishua.lib.utils.AsStrUtils;
import com.rjwh.dingdong.client.application.MyApplication;
import com.rjwh.dingdong.client.bean.localbean.DownloadInfo;
import com.rjwh.dingdong.client.download.task.DownloadThreadPool;
import com.rjwh.dingdong.client.download.task.ExecutorWithListener;
import com.rjwh.dingdong.client.util.FileUtils;
import com.rjwh.dingdong.client.util.LogUtil;

import java.io.File;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

public class DownloadManager {
    public static final int STATE_NONE = 0;
    /**
     * 等待中
     */
    public static final int STATE_WAITING = 1;
    /**
     * 下载中
     */
    public static final int STATE_DOWNLOADING = 2;
    /**
     * 暂停
     */
    public static final int STATE_PAUSED = 3;
    /**
     * 下载完毕
     */
    public static final int STATE_DOWNLOADED = 4;
    /**
     * 下载失败
     */
    public static final int STATE_ERROR = 5;

    /**
     * 解压中
     */
    public static final int STATE_UNZIP = 6;

    /**
     * 解压成功
     */
    public static final int STATE_UNZIP_SUCESS = 9;

//	public static final int STATE_UNZIP = 6;
//
//	public static final int STATE_UNZIP_SUCESS = 7;
//
//	public static final int STATE_UNZIP_ERROR = 8;

    private static NumberFormat numberFormat = NumberFormat.getInstance();

    private static DownloadManager instance;


    private List<DownloadInfo> mDownloadInfoList;   //维护了所有下载任务的集合

    private DownloadManager() {
        threadPool = new DownloadThreadPool();
        mDownloadInfoList = Collections.synchronizedList(new ArrayList<DownloadInfo>());
        mDownloadInfoList = MyApplication.db.findAll(DownloadInfo.class);
        for (DownloadInfo info : mDownloadInfoList) {
//            LogUtil.d("DownloadManager","id:"+info.getGameId()+" downlength"+info.getDownloadLength());
            //校验数据的有效性，防止下载过程中退出，第二次进入的时候，由于状态没有更新导致的状态错误
            if (info.getDownloadState() == STATE_WAITING || info.getDownloadState() == STATE_DOWNLOADING) {
                info.setDownloadState(STATE_PAUSED);
                MyApplication.db.update(info);
            }
        }
    }


    public static synchronized DownloadManager getInstance() {
        if (instance == null) {
            instance = new DownloadManager();
        }
        return instance;
    }


    private DownloadThreadPool threadPool;          //下载的线程池

    public DownloadThreadPool getThreadPool() {
        return threadPool;
    }



    public void addTask(DownloadInfo info){
        if(info!=null){
            if(info.getGameId() == 0 || info.getGameName() ==null ||
                    info.getGamePic() ==null || AsStrUtils.isEmpty(info.getUrl())){
                return;
            }
            addTask(info.getGameId(),info.getType(),info.getGameName(),info.getGamePic(), info.getVersion(),info.getUrl(),false);
        }
    }

    public void addTask(DownloadInfo info,boolean flag){
        if(info!=null){
            if(info.getGameId() == 0 || info.getGameName() ==null ||
                    info.getGamePic() ==null || info.getUrl() ==null ){
                return;
            }
            addTask(info.getGameId(),info.getType(),info.getGameName(),info.getGamePic(), info.getVersion(),info.getUrl(),flag);
        }
    }
    /**
     * 添加一个下载任务
     *
     * @param url       下载地址
     * @param isRestart 是否重新开始下载
     */
    private void addTask(@NonNull int id,@NonNull int type,@NonNull String name,@NonNull String pic,@NonNull String version,@NonNull String url, boolean isRestart) {
        DownloadInfo downloadInfo = getTaskByUrl(id);
        if (downloadInfo == null) {
            downloadInfo = new DownloadInfo();
            downloadInfo.setUrl(url);
            downloadInfo.setGameId(id);
            downloadInfo.setGameName(name);
            downloadInfo.setGamePic(pic);
            downloadInfo.setType(type);
            downloadInfo.setVersion(version);
            downloadInfo.setTargetFolder(FileUtils.getDownloadDirectory());
            downloadInfo.setDownloadState(DownloadManager.STATE_NONE);
            MyApplication.db.save(downloadInfo);
            mDownloadInfoList.add(downloadInfo);
        }
        //无状态，暂停，错误才允许开始下载
        if (downloadInfo.getDownloadState() == DownloadManager.STATE_PAUSED) {
            //构造即开始执行
            DownloadTask downloadTask = new DownloadTask(downloadInfo,false);
            downloadInfo.setTask(downloadTask);
        }else if(downloadInfo.getDownloadState() == DownloadManager.STATE_NONE || downloadInfo.getDownloadState() == DownloadManager.STATE_ERROR){
            DownloadTask downloadTask = new DownloadTask(downloadInfo,true);
            downloadInfo.setTask(downloadTask);
        } else {
            LogUtil.d("DownloadManager", "任务正在下载或等待中 url:" + url);
        }
    }

    /** 开始所有任务的方法 */
    public void startAllTask() {
        for (DownloadInfo downloadInfo : mDownloadInfoList) {
            addTask(downloadInfo);
        }
    }

    /** 暂停的方法 */
    public void pauseTask(int id) {
        DownloadInfo downloadInfo = getTaskByUrl(id);
        if (downloadInfo == null) return;
        int state = downloadInfo.getDownloadState();
        //等待和下载中才允许暂停
        if ((state == STATE_DOWNLOADING || state == STATE_WAITING) && downloadInfo.getTask() != null) {
            LogUtil.d("HTML","调用暂停");
            downloadInfo.getTask().pause();
        }
    }

    /** 暂停全部任务,先暂停没有下载的，再暂停下载中的 */
    public void pauseAllTask() {
        for (DownloadInfo info : mDownloadInfoList) {
            if (info.getDownloadState() != STATE_DOWNLOADING) pauseTask(info.getGameId());
        }
        for (DownloadInfo info : mDownloadInfoList) {
            if (info.getDownloadState() == STATE_DOWNLOADING) pauseTask(info.getGameId());
        }
    }

    /** 停止的方法 */
    public void stopTask(final int id) {
        DownloadInfo downloadInfo = getTaskByUrl(id);
        if (downloadInfo == null) return;
        //无状态和完成状态，不允许停止
        if ((downloadInfo.getDownloadState() != STATE_NONE && downloadInfo.getDownloadState() != STATE_DOWNLOADED) && downloadInfo.getTask() != null) {
            downloadInfo.getTask().stop();
        }
    }

    /** 停止全部任务,先停止没有下载的，再停止下载中的 */
    public void stopAllTask() {
        for (DownloadInfo info : mDownloadInfoList) {
            if (info.getDownloadState() != STATE_DOWNLOADING) stopTask(info.getGameId());
        }
        for (DownloadInfo info : mDownloadInfoList) {
            if (info.getDownloadState() == STATE_DOWNLOADING) stopTask(info.getGameId());
        }
    }

    /** 删除一个任务 */
    public void removeTask(final int id) {
        final DownloadInfo downloadInfo = getTaskByUrl(id);
        if (downloadInfo == null) return;
        pauseTask(id);        //暂停任务
        removeTaskByUrl(id);  //移除任务
        deleteFile(downloadInfo.getTargetPath()); //删除文件
        MyApplication.db.deleteByWhere(DownloadInfo.class,"gameId="+id);
    }

    public void removeTaskByUrl(@NonNull int id) {
        ListIterator<DownloadInfo> iterator = mDownloadInfoList.listIterator();
        while (iterator.hasNext()) {
            DownloadInfo info = iterator.next();
            if (id == info.getGameId()) {
                iterator.remove();         //清除任务
                break;
            }
        }
    }

    /** 删除所有任务 */
    public void removeAllTask() {
        //集合深度拷贝，避免迭代移除报错
        List<Integer> urls = new ArrayList<>();
        for (DownloadInfo info : mDownloadInfoList) {
            urls.add(info.getGameId());
        }
        for (Integer url : urls) {
            removeTask(url);
        }
    }

    /** 重新下载 */
    public void restartTask(final int id) {
        final DownloadInfo downloadInfo = getTaskByUrl(id);
        if (downloadInfo.getDownloadState() == STATE_DOWNLOADING) {
            //如果正在下载中，先暂停，等任务结束后再添加到队列开始下载
            pauseTask(id);
            threadPool.getExecutor().addOnTaskEndListener(new ExecutorWithListener.OnTaskEndListener() {
                @Override
                public void onTaskEnd(Runnable r) {
                    if (r == downloadInfo.getTask().getRunnable()) {
                        //因为该监听是全局监听，每次任务被移除都会回调，所以以下方法执行一次后，必须移除，否者会反复调用
                        threadPool.getExecutor().removeOnTaskEndListener(this);
                        addTask(downloadInfo,true); //此时监听给空，表示会使用之前的监听，true表示重新下载，会删除临时文件
                    }
                }
            });
        } else {
            pauseTask(id);
            startTask(id);
        }
    }

    /** 重新开始下载任务 */
    private void startTask(@NonNull int id) {
        DownloadInfo downloadInfo = getTaskByUrl(id);
        if (downloadInfo == null) return;
        if (downloadInfo.getDownloadState() != STATE_DOWNLOADING) {
            DownloadTask downloadTask = new DownloadTask(downloadInfo,true);
            downloadInfo.setTask(downloadTask);
        }
    }

    /** 根据路径删除文件 */
    private boolean deleteFile(String path) {
        if (TextUtils.isEmpty(path)) return true;
        File file = new File(path);
        if (!file.exists()) return true;
        if (file.isFile()) return file.delete();
        return false;
    }

    public DownloadInfo getTaskByUrl(@NonNull int id) {
        for (DownloadInfo downloadInfo : mDownloadInfoList) {
            if (id == downloadInfo.getGameId()) {
                return downloadInfo;
            }
        }
        return null;
    }

    public List<DownloadInfo> getmDownloadInfoList(){
        return  mDownloadInfoList;
    }
}
